home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 026-050 / scopedisk47 / ls22 / lssup.a < prev   
Text File  |  1995-03-18  |  22KB  |  834 lines

  1. * --------------------------------------------------------------------- *
  2. * LSSUP.A    - Assembly support routines for ls.c            *
  3. * Copyright © 1988 by Justin V. McCormick. All Rights Reserved.        *
  4. * --------------------------------------------------------------------- *
  5.     BASEREG    B
  6.     SMALLOBJ
  7.     ADDSYM
  8.     OPTIMON
  9.  
  10.     IDNT    "lssup.a"
  11.  
  12.     include "asm:inc/macros.i"
  13.  
  14.  
  15. ; Equates
  16. fib_FileName    equ    $8
  17. fib_Size    equ    $7C
  18. fib_NumBlocks    equ    $80
  19. fib_DateStamp    equ    $84
  20.  
  21. ds_Days        equ    $0
  22. ds_Minute    equ    $4
  23. ds_Tick        equ    $8
  24.  
  25. _LVOAddPort    equ    $FE9E
  26. _LVOAllocMem    equ    $FF3A
  27. _LVOAllocSignal    equ    $FEB6
  28. _LVODebug    equ    $FF8E
  29. _LVOFindTask    equ    $FEDA
  30. _LVOFreeMem    equ    $FF2E
  31. _LVOFreeSignal    equ    $FEB0
  32. _LVOGetMsg    equ    $FE8C
  33. _LVOPutMsg    equ    $FE92
  34. _LVORawDoFmt    equ    $FDF6
  35. _LVORemPort    equ    $FE98
  36. _LVORead    equ    $FFD6
  37. _LVOWaitPort    equ    $FE80
  38. _LVOWrite    equ    $FFD0
  39.  
  40. pr_ConsoleTask        EQU    $A4 
  41. MEMF_CLEAR        EQU    $10000 
  42. MEMF_PUBLIC        EQU    $1 
  43. sp_Msg            EQU    $0 
  44. sp_Pkt            EQU    $14 
  45. sp_SIZEOF        EQU    $44 
  46. dp_Link            EQU    $0 
  47. dp_Port            EQU    $4 
  48. dp_Arg1            EQU    $14 
  49. dp_Type            EQU    $8 
  50. ACTION_SCREEN_MODE    EQU    $3E2 
  51. LN_NAME            EQU    $A 
  52. LN_PRI            EQU    $9 
  53. LN_TYPE            EQU    $8 
  54. MP_FLAGS        EQU    $E 
  55. MP_MSGLIST        EQU    $14 
  56. MP_SIGBIT        EQU    $F 
  57. MP_SIGTASK        EQU    $10 
  58. MP_SIZE            EQU    $22 
  59. NT_MSGPORT        EQU    $4 
  60. PA_SIGNAL        EQU    $0 
  61.  
  62. * External constants
  63.     XREF    _DOSBase
  64.     XREF    _Out
  65.     XREF    _In
  66.  
  67.     SECTION    CODE
  68.  
  69. * ------------------------------------------------------------------------- *
  70. * void asprintf(wstr, formatstring, args)
  71. *   char *wstr;
  72. *   char *formatstring;
  73. *   char **args;
  74. * Synopsis: Given formatstring and args to format, formats output to wstr.
  75. * Similar to sprintf(), except doesn't handle floats.
  76. * ------------------------------------------------------------------------- *
  77.     XDEF    _asprintf
  78. _asprintf:
  79.     link    a5,#0
  80.     movem.l    d0-d2/a0-a3,-(sp)    ;Save everything we might clobber
  81.  
  82. * Call format function to convert fmtstring and args to buffer on the stack
  83.     movea.l    12(a5),a0        ;Grab format string
  84.     lea    16(a5),a1        ;Grab EA of arguments
  85.     lea    kput1,a2        ;Grab EA of output subroutine
  86.     movea.l    8(a5),a3        ;Grab EA of dest workspace
  87.     SYS    RawDoFmt,4        ;Format it into workspace
  88.  
  89.     movem.l    (sp)+,d0-d2/a0-a3    ;Restore registers
  90.     unlk    a5            ;And stack frame
  91.     rts
  92.  
  93. * ------------------------------------------------------------------------- *
  94. * RawDoFmt() output routine for xprintf, called for each formatted char.
  95. * Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
  96. * ------------------------------------------------------------------------- *
  97.     XDEF    kput1
  98. kput1:
  99.     move.b    d0,(a3)+
  100.     rts
  101.  
  102. * --------------------------------------------------------------------- *
  103. * void GetWinBounds(width, height)
  104. *   long *width, *height;
  105. *
  106. * Find current console window, determine width and height
  107. * in terms of current font, update width and height VPARMS passed.
  108. * --------------------------------------------------------------------- *
  109. rpstr    equ    -32
  110. rpport    equ    -12
  111. packet    equ    -8
  112. conid    equ    -4
  113.  
  114. width    equ    8
  115. height    equ    12
  116.  
  117.     XDEF    _GetWinBounds
  118. _GetWinBounds:
  119.     link    a5,#-32
  120.     movem.l    d2-d4/a2,-(sp)
  121.  
  122.     suba.l    a1,a1
  123.     SYS    FindTask,4        ;d0 = FindTask(0L), our process
  124.     movea.l    d0,a0            ;Transfer to address reg
  125.     move.l    pr_ConsoleTask(a0),conid(a5) ;Save proc->pr_ConsoleTask
  126.  
  127.     moveq    #0,d4            ;Clear our success status register
  128.  
  129.     moveq    #0,d0
  130.     movea.l    d0,a0
  131.     bsr.w    CreatePort(pc)
  132.     move.l    d0,rpport(a5)        ;rpport = CreatePort(0L, 0L)
  133.      beq.w    gwbdone            ;Oops, no signals or ram available!
  134.     move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  135.     moveq    #sp_SIZEOF,d0
  136.     SYS    AllocMem
  137.     move.l    d0,packet(a5)        ;packet = AllocMem(sizeof(*packet),MEMF_PUBLIC|MEMF_CLEAR)
  138.      beq.w    gwbfreeport        ;Oops, no ram, free up port
  139.  
  140. * Okay, we got our process id, reply port, and packet
  141. * Now toggle the console into raw mode
  142.     movea.l    rpport(a5),a2
  143.     movea.l    d0,a1
  144.     movea.l    conid(a5),a0
  145.     moveq    #1,d0
  146.     bsr.w    SetConsoleType(pc)    ;SetConsoleType(1L, conid, packet, rpport)
  147.  
  148. * Request a window bounds report
  149.     moveq    #4,d3
  150.     lea    gwbrstr(a4),a0
  151.     move.l    a0,d2
  152.     move.l    _Out(a4),d1
  153.     SYS    Write,_DOSBase(a4)    ;Write(Output(), "\2330 q", 4L);
  154.     cmpi.l    #$0004,d0        ;Did the console choke on it?
  155.      bne.w    gwbsetcook        ;hmmm, see if we can back out gracefully
  156.  
  157. * Read the report string into stack buffer
  158.     moveq    #16,d3            ;Don't let it get longer than 16 characters
  159.     lea    rpstr(a5),a0        ;Point to input string area
  160.     move.l    a0,d2
  161.     move.l    _In(a4),d1
  162.     SYS    Read            ;Read(Input(), rpstr, 16L)
  163.     move.l    d0,d4            ;Save read length while we close shop
  164.  
  165. * Turn the console back to cooked mode pronto to avoid cursor blink
  166. gwbsetcook:
  167.     movea.l    rpport(a5),a2
  168.     movea.l    packet(a5),a1
  169.     movea.l    conid(a5),a0
  170.     moveq    #0,d0
  171.     bsr.w    SetConsoleType(pc)    ;SetConsoleType(0L, conid, packet, rpport)
  172.  
  173. * Release resources we borrowed
  174. gwbfreepack:
  175.     move.l    packet(a5),d0        ;Did we allocate a packet?
  176.      beq.b    gwbfreeport        ;nay, check for port to free
  177.     movea.l    d0,a1
  178.     moveq    #sp_SIZEOF,d0
  179.     SYS    FreeMem            ;Else FreeMem(packet, sizeof(*packet))
  180.  
  181. gwbfreeport:
  182.     move.l    rpport(a5),d0        ;if (rpport)...
  183.      beq.w    gwbdone            ;nope
  184.     bsr.w    DeletePort(pc)        ;Else DeletePort(rpport)
  185.  
  186. * Finally, sanity check window bounds report string
  187. * d4 = length of report string according to Read()
  188.     cmpi.l    #9,d4            ;Less than 8 characters returned?
  189.      ble.w    gwbdone            ;hmmm, phonky bounds report from DOS?
  190.     lea    rpstr(a5),a2        ;a2 = rpstr
  191.     cmpi.b    #';',4(a2)        ;Matches a typical report template?
  192.      bne.w    gwbdone            ;nope, got some weird junk back?
  193.     cmpi.b    #'r',-1(a2,d4.w)    ;Last byte is 'r' for report?
  194.      bne.w    gwbdone            ;Nope, message fubar!
  195.  
  196. * Parse the height and width variables from the field now
  197. * Our report format looks like this in hex:
  198. *     9b 31 3b 31 3b y2 y1 3b x2 x1 20 72
  199. * Or in ascii:
  200. *    <0x9b>1;1;20;77 r
  201. * Which would indicate a width of 77 cols and a height of 20 rows for
  202. * the current console device
  203. *
  204. * REGS:    a2 points to beginning of 'r' terminated string
  205.  
  206.     lea    5(a2),a2        ;Point to first char of Y size
  207.     moveq    #0,d1            ;Clear out work reg
  208.  
  209. * Convert ascii rows value to LONG, update host data
  210.     move.b    (a2)+,d1        ;Grab a Y
  211.     subi.w    #'0',d1            ;Less ascii offset
  212.     cmpi.b    #';',(a2)        ;Any more Y digits?
  213.      beq.b    1$            ;Nope
  214.     mulu    #10,d1            ;Else shift by 10
  215.     add.b    (a2)+,d1        ;Add least significant Y digit
  216.     subi.b    #'0',d1            ;Less ascii offset
  217.     cmpi.b    #';',(a2)        ;Any more Y digits?
  218.      beq.b    1$            ;Nope
  219.     mulu    #$000a,d1        ;Else shift by 10
  220.     add.b    (a2)+,d1        ;Add least significant Y digit
  221.     subi.b    #'0',d1            ;Less ascii offset
  222.                     ;We'll assume screen height < 999 rows    
  223. 1$
  224. * Convert ascii columns value to LONG, update host data
  225.     addq.w    #1,a2            ;Move past the ';' separator
  226.     moveq    #0,d2            ;Zap work reg
  227.     move.b    (a2)+,d2        ;Grab msd of X
  228.     cmpi.b    #' ',d2            ;Premature end?
  229.      beq.w    gwbdone            ;Huh, must be garbage - don't update VPARMS
  230.     cmpi.b    #';',d2            ;Also a possible error
  231.      beq.w    gwbdone
  232.     cmpi.b    #'r',d2            ;And what about this?
  233.      beq.w    gwbdone
  234.  
  235.     subi.b    #'0',d2            ;Okay, adjust ascii offset
  236.     cmpi.b    #' ',(a2)        ;Hit end of report?
  237.      beq.b    2$            ;Yep
  238.     mulu    #$000a,d2        ;Else shift by 10
  239.     add.b    (a2)+,d2        ;Add next digit
  240.     subi.b    #'0',d2            ;Ascii adjust
  241.     cmpi.b    #' ',(a2)        ;Hit end of report?
  242.      beq.b    2$            ;Yep
  243.     mulu    #$000a,d2        ;Else shift by 10
  244.     add.b    (a2),d2            ;Add next digit
  245.     subi.b    #'0',d2            ;Ascii adjust
  246.  
  247. 2$
  248. * Finally, update parameters by reference
  249.     movea.l    height(a5),a0        ;Grab height VPARM
  250.     move.l    d1,(a0)            ;*height = d1
  251.     movea.l    width(a5),a0        ;Grab width VPARM
  252.     move.l    d2,(a0)            ;*width = d2
  253.  
  254. gwbdone:
  255.     movem.l    (sp)+,d2-d4/a2
  256.     unlk    a5
  257.     rts
  258.  
  259. * --------------------------------------------------------------------- *
  260. * void __asm SetConsoleType(flag, id, packet, port)
  261. *   register __d0 long flag;
  262. *   register __a0 struct Process *id;
  263. *   register __a1 struct StandardPacket *packet;
  264. *   register __a2 struct MsgPort *port;
  265. *
  266. * Flag = 1L -- Raw mode
  267. *      = 0L -- Cooked mode
  268. * --------------------------------------------------------------------- *
  269.     XDEF    SetConsoleType
  270. SetConsoleType:
  271.     movem.l    a3/a5,-(sp)
  272.  
  273.     movea.l    a0,a3            ;Copy process pointer
  274.     movea.l    a1,a5            ;Copy packet pointer
  275.     lea    sp_Pkt(a5),a0        ;a0 = &packet->sp_Pkt
  276.     move.l    a0,sp_Msg+LN_NAME(a5)    ;p->sp_Msg.mn_Node.ln_Name = &p->sp_Pkt
  277.     lea    sp_Msg(a5),a0        ;a0 = &packet->sp_Msg
  278.     move.l    a0,sp_Pkt+dp_Link(a5)    ;p->sp_Pkt.dp_Link = &p->sp_Msg
  279.     move.l    a2,sp_Pkt+dp_Port(a5)    ;p->sp_Pkt.dp_Port = replyport
  280.     move.l    #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a5)    ;Set function
  281.  
  282.     tst.w    d0            ;On or Off?
  283.      beq.w    1$
  284.     move.l    #-1,sp_Pkt+dp_Arg1(a5)    ;RAW ON
  285.     bra.b    2$
  286. 1$
  287.     clr.l    sp_Pkt+dp_Arg1(a5)    ;RAW OFF
  288. 2$
  289.     movea.l    a3,a0
  290.     movea.l    a5,a1
  291.     SYS    PutMsg,4        ;PutMsg(proc, packet)
  292.  
  293.     movea.l    a2,a0
  294.     SYS    WaitPort        ;WaitPort(port)
  295.     movea.l    a2,a0
  296.     SYS    GetMsg            ;(void)GetMsg(port)
  297.  
  298.     movem.l    (sp)+,a3/a5
  299.     rts
  300.  
  301. * ------------------------------------------------------------------------- *
  302. * struct MsgPort *CreatePort(name, pri) (a0/d0)
  303. * ------------------------------------------------------------------------- *
  304.     XDEF    CreatePort
  305. CreatePort:
  306.     movem.l    d5/d7/a2/a5,-(sp)
  307.  
  308.     move.l    a0,a5            ;Save Name
  309.     move.l    d0,d5            ;Save Pri
  310.  
  311. * Allocate a free signal, crap out if we can't
  312.     moveq    #-1,d0
  313.     SYS    AllocSignal,4
  314.     cmp.l    #-1,d0            ;Did we get a signal?
  315.      bne.b    cpgotsig        ;Yep
  316.     moveq    #0,d0            ;Otherwise return NULL
  317.     bra.w    cpdone
  318.  
  319. cpgotsig:
  320.     move.l    d0,d7            ;Save our signal
  321.  
  322. * Allocate memory for MsgPort
  323.     moveq.l    #MP_SIZE,d0        ;Size of MsgPort
  324.     move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1    ;Type of memory
  325.     SYS    AllocMem        ;Allocate it
  326.     tst.l    d0            ;Did we get it?
  327.      bne.b    cpgotport        ;Yep
  328.  
  329.     move.l    d7,d0            ;Otherwise crap out, free signal
  330.     SYS    FreeSignal
  331.     moveq    #0,d0            ;Return NULL
  332.     bra.w    cpdone
  333.  
  334. cpgotport:
  335.     move.l    d0,a2            ;This is our new port!
  336.     move.l    a5,LN_NAME(a2)        ;port->mp_Node.ln_Name = name
  337.     move.b    d5,LN_PRI(a2)        ;port->mp_Node.ln_Pri = priority
  338.     move.b    #NT_MSGPORT,LN_TYPE(a2) ;port->mp_Node.ln_Type = NT_MSGPORT
  339.     move.b    #PA_SIGNAL,MP_FLAGS(a2) ;port->mp_Flags = PA_SIGNAL
  340.     move.b    d7,MP_SIGBIT(a2)    ;port->mp_SIGBIT = sigBit
  341.     suba.l    a1,a1
  342.     SYS    FindTask
  343.     move.l    d0,MP_SIGTASK(a2)    ;port->mp_SIGTASK = FindTask(0L)
  344.     
  345.     cmpa.l    #0,a5            ;Is this a new name?
  346.     beq.b    cpnoname        ;Nope, add it to the msg list
  347.  
  348.     movea.l    a2,a1
  349.     SYS    AddPort            ;Otherwise add this port
  350.     move.l    a2,d0            ;Return port pointer
  351.     bra.b    cpdone
  352.  
  353. cpnoname:
  354. * Initialized New List head
  355.     lea    MP_MSGLIST(a2),a0     ;a0 = &port->mp_MsgList
  356.     move.l    a0,(a0)            ;list->lh_Head = list
  357.     addq.l    #4,(a0)            ;list->lh_Head += 4L
  358.     clr.l    4(a0)            ;list->lh_Tail = 0L
  359.     move.l    a0,8(a0)        ;list->lh_TailPred = list
  360.     move.l    a2,d0            ;Return port pointer
  361.  
  362. cpdone:
  363.     movem.l    (sp)+,d5/d7/a2/a5
  364.     rts
  365.  
  366. * ------------------------------------------------------------------------- *
  367. * DeletePort(port)(d0)
  368. * ------------------------------------------------------------------------- *
  369.     XDEF    DeletePort
  370. DeletePort:
  371.     move.l    a5,-(sp)
  372.  
  373.     move.l    d0,a5
  374.     tst.l    LN_NAME(a5)        ;Is there a name?
  375.     beq.s    dpnoname
  376.     
  377.     move.l    d0,a1
  378.     SYS    RemPort,4        ;RemPort(port)
  379.     
  380. dpnoname:
  381.     move.b    #$ff,LN_TYPE(a5)     ;port->mp_Node.ln_Type = 0xff
  382.     move.l    #-1,MP_MSGLIST(a5)     ;port->mp_MsgList.lh_Head = -1L
  383.  
  384.     moveq    #0,d0
  385.     move.b    MP_SIGBIT(a5),d0    ;d0 = port->mp_SigBit
  386.     SYS    FreeSignal,4        ;FreeSignal(d0)
  387.  
  388.     moveq    #MP_SIZE,d0
  389.     move.l    a5,a1
  390.     SYS    FreeMem            ;FreeMem(port, sizeof(*port))
  391.  
  392.     move.l    (sp)+,a5
  393.     rts
  394.  
  395. * ------------------------------------------------------------------------
  396. * char *FibFileDate(fib_date)
  397. *   register struct DateStamp *fib_date;
  398. *
  399. *   Calculate date based on DateStamp structure and return a pointer
  400. * to the formatted date string.
  401. * ------------------------------------------------------------------------
  402.     XDEF    _FibFileDate
  403. _FibFileDate:
  404.     link    a5,#0
  405.     movem.l    d3-d7/a4,-(sp)
  406.  
  407.     movea.l    8(a5),a1        ;Grab datestamp pointer
  408.     moveq    #78,d7            ;Initial year = 1978
  409.  
  410.     move.l    (a1),d5            ;days = fib_date->ds_Days
  411.      blt.w    ffdbaddate        ;Hey! you can't be negative! Invalid date...
  412.  
  413. * Determine what year it is
  414.     divu    #1461,d5
  415.     move.l    d5,d0            ;Stash it
  416.     ext.l    d5
  417.     lsl.l    #2,d5
  418.     add.l    d5,d7            ;year += (days / 1461) * 4
  419.  
  420. * Count how many months into that year
  421. ffdgetmo:
  422.     swap    d0            ;days %= 1461
  423.     move.w    d0,d5
  424.  
  425. 1$    tst.w    d5            ;Out of days yet?
  426.      beq.b    3$            ;Yep, done here
  427.  
  428.     move.w    #365,d6            ;Else month_days = 365
  429.     move.w    d7,d0            ;Grab year
  430.     andi.w    #3,d0            ;if (year & 3) == 0 Leap year?
  431.      bne.b    2$            ;Nope
  432.     addq.w    #1,d6            ;Otherwise bump month_days
  433.  
  434. 2$    cmp.w    d6,d5            ;is day < month_days?
  435.      blt.b    3$            ;yep, done here
  436.     sub.w    d6,d5            ;otherwise day -= month_days
  437.  
  438.     addq.l    #1,d7            ; year++
  439.     bra.b    1$
  440. 3$
  441.  
  442. * Count how many days into that month of that year
  443. ffdgetday:
  444. ;for (i = 0, day++; i < 12; i++)
  445.     moveq    #0,d4            ;current month = 0
  446.     moveq    #0,d6            ;Zap hinybs
  447.     addq.w    #1,d5
  448.     lea    _dayspermonth(a4),a0
  449.  
  450. 1$
  451.     move.b    0(a0,d4.w),d6        ;month_days = dayspermonth[i]
  452.  
  453.     cmpi.w    #1,d4            ;if (i == 1 && (year & 3) == 0)
  454.      bne.b    2$
  455.     move.w    d7,d0
  456.     andi.w    #3,d0
  457.      bne.b    2$
  458.     addq.w    #1,d6            ;month_days++
  459.  
  460. 2$    cmp.w    d6,d5            ;if (day <= month_days)
  461.      ble.b    4$            ;Break out, found the right month
  462.  
  463.     sub.w    d6,d5            ;Else, day -= month_days
  464.  
  465.     addq.w    #1,d4            ;i++
  466. 3$    cmpi.w    #12,d4            ;Done all months yet?
  467.      blt.b    1$            ;Nope
  468.  
  469. 4$
  470. ffdprint:
  471. 1$    cmpi.l    #99,d7            ;while (year >= 100)
  472.      ble.b    2$
  473.     subi.l    #100,d7            ;year -= 100
  474.     bra.b    1$
  475. 2$
  476. ;asprintf(datestr, "%02d-%02d-%02d %02d:%02d:%02d", i + 1, day, year, hour, min, sec)
  477.     move.l    8(a1),d0        ;sec = fib_date->ds_Tick / 50;
  478.     divu    #50,d0
  479.     move.w    d0,-(sp)        ;Push secs
  480.  
  481.     moveq    #0,d0            ;Zap reg
  482.     move.w    6(a1),d0        ;min = fib_date->ds_Minute
  483.     move.w    d0,d1            ;Clone it
  484.     divu    #60,d0
  485.     move.w    d0,d3            ;hour = min / 60
  486.     mulu    #60,d0
  487.     sub.w    d0,d1            ;min -= hour * 60
  488.     move.w    d1,-(sp)        ;Push mins
  489.  
  490.     move.w    d3,-(sp)        ;Push hours
  491.     addq.w    #1,d4            ;Push day of month (offset by 1!)
  492.     move.w    d5,-(sp)        ;Push month
  493.     move.w    d4,-(sp)
  494.     move.w    d7,-(sp)        ;Push year
  495.     pea    _datepat(a4)        ;Push the format pattern
  496.     pea    _datestr(a4)        ;Push destination buffer
  497.     jsr    _asprintf(pc)    
  498.     lea    20(sp),sp
  499.     lea    _datestr(a4),a0
  500.     move.l    a0,d0            ;return((char *)&datestr[0])
  501.  
  502. ffddone:
  503.     movem.l    (sp)+,d3-d7/a4
  504.     unlk    a5
  505.     rts
  506.  
  507. ffdbaddate:
  508.     lea    _baddatestr(a4),a0    ;return (" <Invalid Date> ");
  509.     move.l    a0,d0
  510.     bra.b    ffddone
  511.  
  512. *----------------------------------------------------------------------
  513. * LONG iswild(name)
  514. *   char *name;
  515. *
  516. * Search a string for wild characters, return 1 if found
  517. *----------------------------------------------------------------------
  518.     XDEF    _iswild
  519. _iswild:
  520.     movea.l    4(sp),a0        ;Grab string pointer
  521.     moveq    #0,d0            ;Clear out our character register
  522. ischk1:
  523.     move.b    (a0)+,d0        ;Grab a char
  524.      beq.b    iwdone            ;Might be end of string?
  525.     cmpi.b    #'*',d0            ;Is it *?
  526.      beq.b    iswdone            ;yep, is wild
  527.     cmpi.b    #'?',d0            ;Is it a qmark
  528.      bne.b    ischk1            ;Nope, check next character
  529.  
  530. iswdone:
  531.     moveq    #1,d0
  532. iwdone:
  533.     rts
  534.  
  535.  
  536. * ------------------------------------------------------------------------
  537. ; Compare a wild card name with a normal name
  538. ; LONG wildmatch (name, wild)
  539. ;   char *name, *wild;
  540. * ------------------------------------------------------------------------
  541.     XDEF    _wildmatch
  542. _wildmatch:
  543.     link    a5,#-64
  544.     movem.l    d3/a2-a3,-(sp)
  545.  
  546.     movea.l    8(a5),a2        ;Grab name
  547.     movea.l    12(a5),a3        ;Grab pattern
  548.     lea    -64(a5),a0        ;back[0][0]
  549.     lea    -60(a5),a1        ;back[0][1]
  550.  
  551.     moveq    #0,d3            ;bi = 0
  552.  
  553. wmloop1:
  554.     tst.b    (a2)            ;End of name?
  555.      bne.b    wmnoteon
  556.     tst.b    (a3)            ;End of pattern?
  557.      beq.w    wmmatched        ;Yep, we matched
  558.  
  559. wmnoteon:
  560.     cmpi.b    #'*',(a3)        ;Is it a splat?
  561.      bne.b    wmnotstar        ;Nope, maybe '?'
  562.  
  563.     cmpi.w    #64,d3            ;Have we hit max expression depth?
  564.      beq.w    wmnomatch        ;Yep, ran out of room in recursion table
  565.  
  566. ;back[bi][0] = w
  567.     move.l    a3,0(a0,d3.w)        ;Stash pointer to this '*' in table
  568.  
  569. ;back[bi][1] = n
  570.     move.l    a2,0(a1,d3.w)
  571.  
  572.     addq.w    #8,d3            ;++bi
  573.     addq.w    #1,a3            ;++w
  574.     bra.b    wmloop1            ;Check next
  575.  
  576. wmgoback:
  577.     subq.w    #8,d3            ;--bi
  578.     move.l    a0,d0
  579. wmback1:
  580.     tst.w    d3            ;while (bi >= 0 && *back[bi][1] == '\x0')
  581.      blt.b    wmbacked
  582.     movea.l    0(a1,d3.l),a0
  583.     tst.b    (a0)
  584.      bne.b    wmbacked
  585.  
  586.     subq.w    #8,d3            ;--bi
  587.     bra.b    wmback1
  588.  
  589. wmbacked:
  590.     tst.w    d3            ;if (bi < 0)
  591.      blt.b    wmnomatch        ;return (0)
  592.  
  593.     movea.l    d0,a0
  594.     movea.l    0(a0,d3.w),a3        ;w = back[bi][0] + 1
  595.     addq.w    #1,a3    
  596.  
  597.     addq.l    #1,0(a1,d3.w)
  598.     movea.l    0(a1,d3.l),a2        ;n = ++back[bi][1]
  599.  
  600.     addq.w    #8,d3            ;++bi
  601.     bra.b    wmloop1
  602.  
  603. wmnotstar:
  604.     cmpi.b    #'?',(a3)        ;Is it '?'
  605.      bne.b    wmnotqmark
  606.  
  607.     tst.b    (a2)            ;Reached end of string?
  608.      bne.b    wmincpoint        ;Nope, move on to next char
  609.  
  610.     tst.w    d3            ;Are we at top level of expression?
  611.      beq.b    wmnomatch        ;Yep, expression didn't match
  612.     bra.b    wmgoback        ;Otherwise pop a level and try to match
  613.  
  614. wmnotqmark:
  615.     move.b    (a2),d0            ;Grab a char from bstr
  616.     cmpi.b    #$40,d0            ;less than @ character?
  617.      bls.b    1$            ;Yep
  618.     cmpi.b    #$5a,d0            ;Greater than Z?
  619.      bhi.b    1$            ;Yep
  620.     addi.b    #$20,d0
  621. 1$
  622.     move.b    (a3),d1            ;Grab a char from bstr
  623.     cmpi.b    #$40,d1            ;less than @ character?
  624.      bls.b    2$            ;Yep
  625.     cmpi.b    #$5a,d1            ;Greater than Z?
  626.      bhi.b    2$            ;Yep
  627.     addi.b    #$20,d1
  628. 2$
  629.     cmp.b    d0,d1            ;*n = *w?
  630.      beq.b    wmincpoint        ;Yep, move on past
  631.  
  632.     tst.w    d3            ;Are we at top expression level?
  633.      beq.b    wmnomatch        ;Yep, they didn't match
  634.     bra.b    wmgoback        ;Nope, process next part
  635.  
  636. wmincpoint:
  637.     tst.b    (a2)            ;Done with name?
  638.      beq.b    wmnamend        ;Yep
  639.     addq.w    #1,a2            ;Otherwise increment name pointer
  640.  
  641. wmnamend:
  642.     tst.b    (a3)            ;End of pattern?
  643.      beq.b    wmmatched        ;Yep, we matched
  644.     addq.w    #1,a3            ;Otherwise inc wild pointer, match next char
  645.     bra.w    wmloop1
  646.  
  647. wmmatched:
  648.     moveq    #1,d0
  649.     bra.b    wmdone
  650.  
  651. wmnomatch:
  652.     moveq    #0,d0
  653.  
  654. wmdone:
  655.     movem.l    (sp)+,d3/a2-a3
  656.     unlk    a5
  657.     rts
  658.  
  659. * --------------------------------------------------------------------- *
  660. * void SortFibs (keytype, direction, fibheadp)
  661. *           d0       d1         a0
  662. *  int keytype;
  663. *  struct FibEntry *fibheadp;
  664. *
  665. * Selection sort a linked list of FibEntrys based on a keycode         *
  666. * --------------------------------------------------------------------- *
  667.     XDEF    _SortFibs
  668. _SortFibs:
  669.     link    a5,#0
  670.     movem.l    d2-d4/a2-a3/a6,-(sp)
  671.  
  672.     movem.l    8(a5),d0-d1/a0
  673.  
  674.     move.l    d0,d2            ;Save keytype
  675.     move.l    d1,d4            ;Save direction of sort
  676.     move.l    a0,d3            ;Save fibheadp
  677.     movea.l    a0,a2            ;a2 = a0 = i
  678.  
  679. sfILoop:
  680.     cmp.l    (a2),d3            ;i->NextFib != fibheadp?
  681.      beq.b    sfdone            ;Nope, wrapped around to start
  682.     movea.l    a2,a6            ;k = i
  683.     movea.l    (a2),a3            ;j = i->NextFib
  684.  
  685. sfJLoop:
  686.     cmp.l    a3,d3            ;j != fibheadp?
  687.      beq.b    sfJdone            ;Nope compared them all, see if swapped any
  688.     movea.l    8(a6),a0        ;a0 = k->Fibp
  689.     movea.l    8(a3),a1        ;a1 = j->Fibp
  690.     move.l    d2,d0            ;d0 = keytype
  691.     jsr    _CompFibs(pc)        ;d0 = CompFibs(keytype, k->Fibp, j->Fibp)
  692.     tst.w    d4            ;Reverse sort?
  693.      beq.b    1$            ;Nope
  694.     bchg.l    #0,d0            ;Else reverse sense of return
  695. 1$
  696.     tst.l    d0            ;Return != 0?
  697.      beq.b    sfNextJ            ;Nope, these two are in order
  698.     movea.l    a3,a6            ;else k = j, this is new swap
  699.  
  700. sfNextJ:
  701.     movea.l    (a3),a3            ;j = j->NextFib
  702.     bra.b    sfJLoop            ;Check bounds
  703.  
  704. sfJdone:
  705.     cmpa.l    a6,a2            ;k != i, did we swap?
  706.      beq.b    sfNextI            ;Nope, i was in correct position already
  707.     move.l    8(a6),d0
  708.     move.l    8(a2),8(a6)
  709.     move.l    d0,8(a2)        ;Else SwapFibs (k, i)
  710.  
  711. sfNextI:
  712.     movea.l    (a2),a2            ;i = i->NextFib
  713.     bra.b    sfILoop            ;Check bounds
  714.  
  715. sfdone:
  716.     movem.l    (sp)+,d2-d4/a2-a3/a6
  717.     unlk    a5
  718.     rts
  719.  
  720. * --------------------------------------------------------------------- *
  721. * int CompFibs (keytype, a, b)
  722. *         d0     a0 a1
  723. *   int keytype;
  724. *   struct FileInfoBlock *a, *b;
  725. *
  726. * Used by SortFibs to determine precedence of Fibs.
  727. * --------------------------------------------------------------------- *
  728.     XDEF    _CompFibs
  729. _CompFibs:
  730.     tst.w    d0            ;Alphabetize?
  731.      bne.b    cfnalpha        ;Nope
  732.  
  733. * Compare lexigraphically, ignoring case differences
  734. cfalpha:
  735.     lea    fib_FileName(a0),a0    ;a = &Fipb->fib_FileName
  736.     lea    fib_FileName(a1),a1    ;b = &Fipb->fib_FileName
  737.  
  738. ;  for(; *a && tolower(*a) == tolower(*b); a++, b++);
  739. lccstart:
  740.     tst.b    (a0)            ;Is there a char here at source?
  741.      beq.b    lcceostr        ;Nope, fell off the end
  742.  
  743.     move.b    (a1)+,d1        ;Grab a char from bstr
  744.     cmpi.b    #$40,d1            ;less than @ character?
  745.      bls.b    1$            ;Yep
  746.     cmpi.b    #$5a,d1            ;Greater than Z?
  747.      bhi.b    1$            ;Yep
  748.     addi.b    #$20,d1
  749. 1$
  750.     move.b    (a0)+,d0        ;Grab a char from astr
  751.     cmpi.b    #$40,d0            ;less than @ character?
  752.      bls.b    2$            ;Yep
  753.     cmpi.b    #$5a,d0            ;Greater than Z?
  754.      bhi.b    2$            ;Yep
  755.     addi.b    #$20,d0
  756. 2$
  757.     cmp.b    d0,d1            ;are they the same?
  758.      beq.b    lccstart        ;Yep, compare next pair of chars
  759.  
  760. lcceostr:
  761.     sub.b    d1,d0            ;return(tolower(*astr) - tolower(*bstr))
  762.      bgt.b    cftrue            ; > 0?, return TRUE
  763.     bra.b    cffalse            ;Else return FALSE
  764.  
  765. cfnalpha:
  766.     subq.w    #1,d0            ;Size?
  767.      bne.b    cfnsize            ;Nope
  768.  
  769. * Compare fib_Sizes
  770.     move.l    fib_Size(a1),d0        ;d0 = bfib->fib_Size
  771.     cmp.l    fib_Size(a0),d0        ;a->fib_Size > b->fib_Size?
  772.      blt.b    cftrue            ;Yep, return TRUE
  773.      bgt.b    cffalse            ;<, return FALSE
  774.     bra.b    cfalpha            ;Else it's a tie, alphabetize
  775.  
  776. cfnsize:
  777.     subq.w    #1,d0            ;Time?
  778.      bne.b    cffalse            ;Nope, an error!
  779.  
  780. * Compare fib_DateStamps
  781.     lea    fib_DateStamp(a0),a0    ;a = &afib->fib_DateStamp
  782.     lea    fib_DateStamp(a1),a1    ;b = &bfib->fib_DateStamp
  783.     move.l    ds_Days(a1),d0        ;d0 = bdate->ds_Days
  784.     cmp.l    ds_Days(a0),d0        ;a->ds_Days > b->ds_Days?
  785.      blt.b    cftrue            ;Yep, a is older
  786.      bgt.b    cffalse            ;Else if a < b, b is older
  787.                     ;Else they are the same day, check min/tick
  788.     move.l    ds_Minute(a0),d0
  789.     sub.l    ds_Minute(a1),d0    ;d0 = amin - bmin
  790.     muls    #3000,d0        ;     * 3000
  791.     add.l    ds_Tick(a0),d0
  792.     sub.l    ds_Tick(a1),d0        ;     + atick - btick
  793.      bgt.b    cftrue            ;Hey, a > b
  794.      blt.b    cffalse            ;a < b, return false
  795.     bra.b    cfalpha            ;Else its the same date, alphabetize
  796.  
  797. cftrue:
  798.     moveq    #1,d0
  799.     rts
  800. cffalse:
  801.     moveq    #0,d0
  802.     rts
  803.  
  804. * --------------------------------------------------------------------- *
  805.     SECTION    __MERGED,DATA
  806. * --------------------------------------------------------------------- *
  807.     XDEF    _dayspermonth
  808. _dayspermonth:
  809.     dc.b    31,28,31,30,31,30,31,31,30,31,30,31
  810.     XDEF    _datepat
  811. _datepat:
  812.     dc.b    '%02d-%02d-%02d %02d:%02d:%02d',0
  813.     CNOP    0,2
  814.     XDEF    _baddatestr
  815. _baddatestr:
  816.     dc.b    '00-00-00 00:00:00',0
  817.     CNOP    0,2
  818.  
  819.     XDEF    gwbrstr
  820. gwbrstr:
  821.     dc.b    $9b,'0 q'
  822.  
  823. * --------------------------------------------------------------------- *
  824.     SECTION    __MERGED,BSS
  825. * --------------------------------------------------------------------- *
  826.     XDEF    _datestr
  827. _datestr:
  828.     ds.b    40
  829.  
  830. * --------------------------------------------------------------------- *
  831.     END
  832. * --------------------------------------------------------------------- *
  833.